package com.googlecode.jmicroerp.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 *
 * @author alex
 */
@Entity
@Table(name = "utilizatori")
public class Utilizator extends AbstractEntitate implements UserDetails {
    private static final long serialVersionUID = 1L;
    private static final int DEFAULT_TIME_UNIT = GregorianCalendar.MINUTE;
    private static final int DEFAULT_UNIT = 30;
    public static final String DEFAULT_PASSWORD = "123456";
    public static final String PASSWORD_PATTERN = "((?=.*\\d).{8,})";
    public static final Integer NUMAR_MAXIM_AUTENTIFICARI_ESUATE = 4;
    private String numeUtilizator;
    private String parola;
    private Integer numarAutentificariEsuate;
    private Date dataExpirareParola;
    private Date dataBlocareCont;
    private List<Rol> roluri;
    private List<GrantedAuthority> authorities;
    private Magazin magazin;

    public Utilizator() {
        super();
    }

    public Utilizator(String numeUtilizator, String parola,
            Integer numarAutentificariEsuate, Date dataExpirareParola) {
        super();
        this.numeUtilizator = numeUtilizator;
        this.parola = parola;
        this.numarAutentificariEsuate = numarAutentificariEsuate;
        this.dataExpirareParola = dataExpirareParola;
    }

    public static Utilizator createUtilizator(String nume, String pass) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.roll(Calendar.YEAR, 2);

        return new Utilizator(nume, pass, 0, calendar.getTime());
    }

    @Column(name = "NUME_UTILIZATOR", length = 100, nullable = false, unique = true)
    public String getNumeUtilizator() {
        return numeUtilizator;
    }

    public void setNumeUtilizator(String numeUtilizator) {
        this.numeUtilizator = numeUtilizator;
    }

    @Column(name = "PAROLA", length = 40, nullable = false)
    public String getParola() {
        return parola;
    }

    public void setParola(String parola) {
        this.parola = parola;
    }

    @Column(name = "AUTENTIFICARI_ESUATE")
    public Integer getNumarAutentificariEsuate() {
        return numarAutentificariEsuate;
    }

    public void setNumarAutentificariEsuate(Integer numarAutentificariEsuate) {
        this.numarAutentificariEsuate = numarAutentificariEsuate;
    }

    @Temporal(value = TemporalType.TIMESTAMP)
    @Column(name = "DATA_EXPIRARE")
    public Date getDataExpirareParola() {
        return dataExpirareParola;
    }

    public void setDataExpirareParola(Date dataExpirareParola) {
        this.dataExpirareParola = dataExpirareParola;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public List<Rol> getRoluri() {
        return roluri;
    }

    public void setRoluri(List<Rol> roluri) {
        this.roluri = roluri;
    }

    @Column(name = "DATA_BLOCARE_CONT")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getDataBlocareCont() {
        return dataBlocareCont;
    }

    public void setDataBlocareCont(Date dataBlocareCont) {
        this.dataBlocareCont = dataBlocareCont;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "MAGAZIN_ID")
    public Magazin getMagazin() {
        return magazin;
    }

    public void setMagazin(Magazin magazin) {
        this.magazin = magazin;
    }

    @Transient
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (authorities == null) {
            authorities = new ArrayList<GrantedAuthority>(roluri.size());
            for (Rol rol : roluri) {
                authorities.add(new SimpleGrantedAuthority(rol.getDenumire()));
            }
            return authorities;
        } else {
            return authorities;
        }
    }

    @Transient
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Transient
    @Override
    /**
     * Cont blocat
     */
    public boolean isAccountNonLocked() {
        boolean deblocat = false;
        if (dataBlocareCont != null) {
            GregorianCalendar deblocareAutomata = new GregorianCalendar();
            deblocareAutomata.setTime(this.dataBlocareCont);
            deblocareAutomata.add(DEFAULT_TIME_UNIT, DEFAULT_UNIT);
            deblocat = new Date().after(deblocareAutomata.getTime());
        }
        if (numarAutentificariEsuate == null) {
            return true;
        }
        return (numarAutentificariEsuate < NUMAR_MAXIM_AUTENTIFICARI_ESUATE)
                || ((numarAutentificariEsuate >= NUMAR_MAXIM_AUTENTIFICARI_ESUATE) && deblocat);
    }

    @Transient
    @Override
    public boolean isCredentialsNonExpired() {
        Date dataCurenta = new Date();
        if (dataExpirareParola == null) {
            return true;
        }
        return dataExpirareParola.after(dataCurenta);
    }

    @Transient
    @Override
    public boolean isEnabled() {
        return true;
    }

    @Transient
    @Override
    public String getPassword() {
        return this.parola;
    }

    @Transient
    @Override
    public String getUsername() {
        return this.numeUtilizator;
    }
}
